﻿using Furion.DatabaseAccessor;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using UpperComputer.Core.Entities;
using YFurion.Application;
using YFurion.Application.EFCore.Extensions;
using YFurion.Extensions;

namespace UpperComputer.Application
{
    public class BaseRoleUserService : EFCoreApplicationService<BaseRoleUser, BaseRoleUserDto, long, BaseRoleUserResultRequestDto>, IBaseRoleUserService
    {
        protected override IQueryable<BaseRoleUser> CreateFilteredQuery(BaseRoleUserResultRequestDto input)
        {
            IQueryable<BaseRoleUser> query = base.CreateFilteredQuery(input)
               .WhereIf(!input.Account.IsNullOrWhiteSpace(), i => i.Account.StartsWith(input.Account));
            return query;
        }

        public async Task<ICollection<BaseRoleUserDto>> GetListWithAccount(string account, CancellationToken cancellationToken = default)
        {
            ICollection<BaseRoleUserDto> baseRoleUserResultDtos = await GetListWithAccounts(new List<string> { account }, cancellationToken);
            return baseRoleUserResultDtos;
        }

        public async Task<ICollection<BaseRoleUserDto>> GetListWithAccounts(List<string> accounts, CancellationToken cancellationToken = default)
        {
            ICollection<BaseRoleUserDto> baseRoleUserResultDtos = await SlaveRepository.AsQueryable()
                .Join(MSRepository.Slave1<BaseRole>().AsQueryable(), bru => bru.RoleCode, br => br.Code, (bru, br) => new BaseRoleUserDto
                {
                    Id = bru.Id,
                    Account = bru.Account,
                    RoleCode = bru.RoleCode,
                    RoleName = br.DisplayName
                })
                .Where(bru => accounts.Contains(bru.Account))
                .ToListAsync(cancellationToken);

            return baseRoleUserResultDtos;
        }

        public async Task DeleteAsync(string account, CancellationToken cancellationToken = default)
        {
            List<BaseRoleUser> baseRoleUsers = await MasterRepository.AsQueryable(bru => bru.Account.Equals(account)).ToListAsync(cancellationToken);
            await MasterRepository.DeleteNowAsync(baseRoleUsers, cancellationToken);
        }

        public async Task<bool> HasPermission(string account, CancellationToken cancellationToken = default)
        {
            IQueryable<BaseRoleUser> query = SlaveRepository
                .Where(u => u.Account.Equals(account))
                .Join(MSRepository.Slave1<BaseRolePermission>().AsQueryable(), brp => brp.RoleCode, br => br.RoleCode, (brp, br) => brp);
            int count = await query.CountAsync(cancellationToken);
            return count > 0 ? true : false;
        }
    }
}
